package org.zjt.gc;

/**
 * Description:
 *
 * @author juntao.zhang
 * Date: 2018-06-01 下午2:40
 * @see
 */
import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;


/**
 *
     那么幻象引用有何实际作用？

         第一、我们可以在监控一个对象什么时候被彻底销毁了。那样，就可以做点什么其他事情（看你是不是有这方面的需求啦）。不过实际中，这种情况也不多的。

         第二、因为理论上存在的，可以通过一个对象的finalize()方法“复活”一个对象，那么如果在一次垃圾回收处理时，调用了一个对象的finalize()（这个方法在何时调用不确定），却让它复活了。要再苦苦等待finalize()的执行，还不知道要到猴年马月的（天下大赦可以有，但不是天天有。谁知道啥时候天朝更替，人主易位）。突然就出现了OutOfMemory错误了。

         而幻象引用绝对不会再让对象复活，只要被它逮着了，事情就简单了：挂定了！

     总而言之，言而总之，归根结底：

     引用是关系垃圾回收的。
 */

class VeryBig{
    private static final int SIZE = 1000000;
    private long[] la = new long[SIZE];
    private String ident;
    public VeryBig(String id) {
        ident = id;
    }
    @Override
    public String toString() {
        return ident;
    }
    @Override
    protected void finalize() {
        System.out.println("finalize...." + ident);
    }
}

public class PhantomReferenceTest {

    private static ReferenceQueue<VeryBig> rq = new ReferenceQueue<VeryBig>();

    public static void checkQueue() {
        Reference<? extends VeryBig> inq = rq.poll();
        if (inq != null) {
            System.out.println("in Queue : " + inq.get());
        }
    }
    public static void main(String[] args) {
        int size = 10;

        LinkedList<PhantomReference<VeryBig>> pa = new LinkedList<PhantomReference<VeryBig>>();
        for (int i = 0; i < size; ++i) {
            pa.add(new PhantomReference<VeryBig>(new VeryBig("phantom " + i), rq));
            System.out.println("just create Phantom : " + pa.getLast().get());
            checkQueue();
        }
    }
}